package com.intretech.umsin.code.generator.component;


import com.intretech.umsin.code.generator.config.GeneratorBaseConfig;
import com.intretech.umsin.code.generator.provider.SchemaProviderFactory;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.micrometer.core.instrument.util.StringUtils;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @version V1.0
 * @ClassName: TemplateHelper
 * @Description:(模板帮助类)
 * @author: 李启联
 * @date: 2020-01-22 14:15
 * @Copyright: Copyright (c), 2020
 */

@Component
public class TemplateHelper {

    @Autowired
    private Configuration config;

    @Autowired
    private GeneratorBaseConfig generatorBaseConfig;

    /**
     *获取文件名
     * @param templateType
     * @param packageName
     * @param className
     * @return
     */
    public String getFileName(TemplateType templateType, String packageName, String className){
        String packagePath = "main" + File.separator + "java" + File.separator;

        if (StringUtils.isBlank(packageName))
            packageName = generatorBaseConfig.getBasePackage();

        if (StringUtils.isNotBlank(packageName)) {
            packagePath += packageName.replace(".", File.separator) + File.separator ;
        }

        switch(templateType){
            case RepositoryTemplate: packagePath += "repository" + File.separator + className + ".java";
                break;
            case EntityTemplate: packagePath += "entity" + File.separator + className + ".java";
                break;
            case EntityTagsTemplate:
            case EntityMetaModelTemplate:
                packagePath += "entity" + File.separator + className + ".java";
                break;
            case ServiceTemplate:   packagePath += "service" + File.separator + className + ".java";
                break;
            case ServiceImplTemplate: packagePath += "service" + File.separator +"impl"+ File.separator + className + ".java";
                break;
            case VoModelTemplate: packagePath += "vo" + File.separator + className + ".java";
                break;
            case VoMapperTemplate: packagePath += "vo" + File.separator + "mapper"+ File.separator+className + ".java";
                break;
            case ControllerTemplate: packagePath += "controller" + File.separator +className + ".java";
                break;
            case ParamQueryPmTemplate:  packagePath += "param" + File.separator +className + ".java";
                break;
            case ParamMapperTemplate:  packagePath += "param" + File.separator + "mapper" +File.separator +className + ".java";
                break;
            case ParamForCtrlTemplate:  packagePath += "param" + File.separator + "ctrl" +File.separator +className + ".java";
                break;
            default: packagePath += "";

        }

        return packagePath;
    }

    /**
     * 渲染模板到Zip文件中
     * @param basePackage 包名
     * @param sourceTable 表名
     * @param className   类名
     * @param templateName 模板名
     * @param zip 存储的zip对象
     */
    public void renderToZip(SchemaProviderFactory schemaProviderFactory, TemplateType templateType, String basePackage, String sourceTable, String className, String templateName, Map<String, Object> dataModel, ZipOutputStream zip) throws Exception {
        if(null == dataModel || dataModel.size()<1)//如果未提供数据模型则创建数据模型
            dataModel = schemaProviderFactory.createDbSchemaProvider().prepareDataModel(sourceTable);

        StringWriter sw = new StringWriter();
        Template template = config.getTemplate(templateName);
        template.process(dataModel, sw);
        try {
            //添加到zip
            zip.putNextEntry(new ZipEntry(this.getFileName(templateType,basePackage,className)));
            IOUtils.write(sw.toString(), zip, "UTF-8" );
        } catch (IOException e) {
            throw new RuntimeException("渲染模板失败，表名：" + sourceTable, e);
        }
        finally {
            IOUtils.closeQuietly(sw);
            zip.closeEntry();
        }
    }
}